package com.gitee.wsl.struct.grammar.parser.result

/**
 * Result of a parse that is either a [parsed value][ParsedValue]
 * or an [error][ParseError].
 */
sealed class ParseResult<out T>

/**
 * Successful result of parsing.
 */
data class ParsedValue<T>(val value: T) : ParseResult<T>()


inline fun <T, R> ParseResult<T>.map(f: (T) -> R): ParseResult<R> {
    return when (this) {
        is ParsedValue -> ParsedValue(f(value))
        is ParseError -> this
    }
}

inline fun <T> ParseResult<T>.getOrElse(f: (ParseError) -> T): T {
    return when (this) {
        is ParsedValue -> value
        is ParseError -> f(this)
    }
}

@Throws(ParseException::class)
fun <T> ParseResult<T>.getOrThrow(): T {
    return when (this) {
        is ParsedValue -> value
        is ParseError -> throw ParseException(this)
    }
}
